package com.ibeetl.admin.console.web;

import com.ibeetl.admin.console.service.DictConsoleService;
import com.ibeetl.admin.console.service.FunctionConsoleService;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.cms.web.query.ArticleQuery;
import com.ibeetl.admin.core.annotation.Function;
import com.ibeetl.admin.core.entity.CoreArea;
import com.ibeetl.admin.core.entity.CoreFile;
import com.ibeetl.admin.core.entity.CoreFunction;
import com.ibeetl.admin.core.file.FileItem;
import com.ibeetl.admin.core.file.FileService;
import com.ibeetl.admin.core.service.CoreAreaService;
import com.ibeetl.admin.core.util.*;
import com.ibeetl.admin.core.web.JsonResult;
import com.ibeetl.cms.entity.CmsArticle;
import com.ibeetl.cms.entity.CmsCatalog;
import com.ibeetl.cms.service.CmsArticleService;
import com.ibeetl.cms.service.CmsArticleTagService;
import com.ibeetl.cms.service.CmsCatalogService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.beetl.sql.core.engine.PageQuery;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * CoreArticle 接口
 */
@Controller
public class ArticleConsoleController {

	private final Log log = LogFactory.getLog(this.getClass());
	private static final String MODEL = "/admin/article";

	@Autowired
	private CmsArticleService articleService;
	@Autowired
	private CmsCatalogService catalogService;
	@Autowired
	private FunctionConsoleService functionConsoleService;
	@Autowired
	private CoreAreaService areaService;
	@Autowired
	FileService fileService;
	@Autowired
	private CmsArticleTagService articleTagService;
	@Autowired
	private DictConsoleService dictConsoleService;
	@Autowired private CorePlatformService corePlatformService;
	/* 页面 */

	@GetMapping(MODEL + "/index.do")
	@Function("admin.article")
	@ResponseBody
	public ModelAndView index() {
		ModelAndView view = new ModelAndView("/admin/article/index.html");
		view.addObject("search", ArticleQuery.class.getName());
		return view;
	}

	@GetMapping(MODEL + "/list.do")
	@Function("admin.article")
	@ResponseBody
	public ModelAndView list(String catalogId) {
		ModelAndView view = new ModelAndView("/admin/article/list.html");

		CmsCatalog catalog = this.catalogService.queryById(NumberUtils.toLong(catalogId));
		if (catalog != null) {
			CoreFunction articleListFunction = this.catalogService.getArticleListFunctionFromCatalogId(catalog.getId());
			if (articleListFunction != null) {
				String url = articleListFunction.getAccessUrl();
				view.setViewName("/admin/article" + url);
			}
		}
		view.addObject("search", ArticleQuery.class.getName());
		return view;
	}

	@GetMapping(MODEL + "/edit.do")
	@Function("admin.article.edit")
	@ResponseBody
	public ModelAndView edit(Integer id) {
		ModelAndView view = new ModelAndView("/admin/article/edit.html");

		CmsArticle article = articleService.queryById(id);
		CmsCatalog catalog = this.catalogService.queryById(article.getCatalogId());
		if (catalog != null) {
			CoreFunction articleListFunction = this.catalogService.getArticleListFunctionFromCatalogId(catalog.getId());
			if (articleListFunction != null) {
				String url = articleListFunction.getAccessUrl();
				view.setViewName("/admin/article" + url);
			}
		}
		view.addObject("article", article);
		return view;
	}

	@GetMapping(MODEL + "/add.do")
	@Function("admin.article.add")
	@ResponseBody
	public ModelAndView add(String catalogId) {
		ModelAndView view = new ModelAndView("/admin/article/edit.html");

		CmsCatalog catalog = this.catalogService.queryById(NumberUtils.toLong(catalogId));
		if (catalog != null) {
			CoreFunction articleListFunction = this.catalogService.getArticleListFunctionFromCatalogId(catalog.getId());
			if (articleListFunction != null) {
				String url = articleListFunction.getAccessUrl();
				view.setViewName("/admin/article" + url);
			}
		}

		return view;
	}

	/* ajax json */

	@PostMapping(MODEL + "/list.json")
	@Function("admin.article.query")
	@ResponseBody
	public JsonResult<PageQuery> list(ArticleQuery condtion) {
		PageQuery page = condtion.getPageQuery();
		articleService.queryByCondition(page);
		return JsonResult.success(page);
	}

	@PostMapping(MODEL + "/add.json")
	@Function("admin.article.add")
	@ResponseBody
	public JsonResult add(@Validated(ValidateConfig.ADD.class) CmsArticle article, HttpServletRequest request) {
		return this.saveOrUpdateArticle(article,request);
	}

	@PostMapping(MODEL + "/update.json")
	@Function("admin.article.edit")
	@ResponseBody
	public JsonResult<String> update(@Validated(ValidateConfig.UPDATE.class) CmsArticle article, HttpServletRequest request) {
		
		return this.saveOrUpdateArticle(article,request);
		

	}

	private JsonResult saveOrUpdateArticle(CmsArticle article, HttpServletRequest request) {

		CmsArticle articleDb = articleService.queryById(article.getId());
		if (articleDb == null) {
			articleDb = new CmsArticle();
			articleDb.setCreateTime(new Date());
		}
		articleDb.setUpdateTime(new Date());
		articleDb = ParamUtil.initParameterObj(request, articleDb);

		if (request.getParameter("fromPage") == null) {
			return JsonResult.failMessage("保存失败：文章内容过多导致无法保存，可缩减文章内容或检查文章中图片格式");
		}

		if (articleDb.getShowTime() == null) {
			articleDb.setShowTime(new Date());
		}

		//保存附件的标题和链接
		String[] attachmentIds = request.getParameterValues("attachment-id[]");
		if (attachmentIds != null) {
			for (String attachmentId : attachmentIds) {
				CoreFile attachment = this.fileService.getCoreFileById(NumberUtils.toLong(attachmentId));
				String title = request.getParameter("attachment-title-" + attachmentId);
				String url = request.getParameter("attachment-url-" + attachmentId);
				attachment.setTitle(title);
				attachment.setUrl(url);
				this.fileService.updateCoreFile(attachment);
			}
		}

		//保存图片的标题和链接
		String[] imageIds = request.getParameterValues("image-id[]");
		if (imageIds != null) {
			for (String imageId : imageIds) {
				CoreFile image = this.fileService.getCoreFileById(NumberUtils.toLong(imageId));
				String title = request.getParameter("image-title-" + imageId);
				String url = request.getParameter("image-url-" + imageId);
				image.setTitle(title);
				image.setUrl(url);
				this.fileService.updateCoreFile(image);
			}
		}

		String provinceCode = request.getParameter("provinceCode");
		String cityCode = request.getParameter("cityCode");
		String countryCode = request.getParameter("countryCode");
		String top = request.getParameter("top");

		CoreArea province = this.areaService.getAreaByAreaCode(NumberUtils.toLong(provinceCode));
		CoreArea city = this.areaService.getAreaByAreaCode(NumberUtils.toLong(cityCode));
		CoreArea country = this.areaService.getAreaByAreaCode(NumberUtils.toLong(countryCode));

		if (province != null) articleDb.setProvince(provinceCode);
		if (city != null) articleDb.setCity(cityCode);
		if (country != null) articleDb.setCountry(countryCode);
		if (StringUtils.equals(top,"1")) {
			articleDb.setTop(true);
			articleDb.setTopTime(new Date());
		} else {
			articleDb.setTop(false);
			articleDb.setTopTime(null);
		}

		/** 此处注释是使用往article_tag 表中存放的方式来记录标签
		String[] tags = request.getParameterValues("tags[]");//传来的参数是用jquery.ajax封装的，对checkbox的参数，会自动增加[]两个字符
		String tagParam = request.getParameter("tags");
		String tag = org.apache.tomcat.util.buf.StringUtils.join(tags) + (tagParam!=null?tagParam:"");//如果checkbox组件中，直选中一个，jquery.ajax只会传positions的参数，只能使用getParameter获得，所以这里要考虑到只选择一个checkbox的情况
		if (StringUtils.isNotBlank(tag)) articleDb.setTag(tag);
		*/

		//此处是使用在article表中存放tag的字典值的方式存放标签，以逗号分隔
		String[] tagValues = request.getParameterValues("tagValues[]");//传来的参数是用jquery.ajax封装的，对checkbox的参数，会自动增加[]两个字符
		String tagValueParam = request.getParameter("tagValues");
		String tagValue = org.apache.tomcat.util.buf.StringUtils.join(tagValues) + (tagValueParam!=null?tagValueParam:"");//如果checkbox组件中，直选中一个，jquery.ajax只会传positions的参数，只能使用getParameter获得，所以这里要考虑到只选择一个checkbox的情况
		if (StringUtils.isNotBlank(tagValue)) articleDb.setTagValue(tagValue);
		articleDb.setUserId(corePlatformService.getCurrentUser().getId());
		int count = articleService.upsert(articleDb);

		//updateArticleTag(article.getId(), tag); 暂时不用往article_tag 表中存放数据，换成使用存放字典的值，以逗号分隔的方式
		if (count > 0) {
			this.corePlatformService.clearArticleCache();
			return new JsonResult().success();
		} else {
			return JsonResult.failMessage("保存失败");
		}
	}

	@GetMapping(MODEL + "/view.json")
	@Function("admin.article.query")
	@ResponseBody
	public JsonResult<CmsArticle> queryInfo(Integer id) {
		CmsArticle article = articleService.queryById(id);
		return JsonResult.success(article);
	}

	@PostMapping(MODEL + "/delete.json")
	@Function("admin.article.delete")
	@ResponseBody
	public JsonResult delete(String ids) {
		if (ids.endsWith(",")) {
			ids = StringUtils.substringBeforeLast(ids, ",");
		}
		List<Long> idList = ConvertUtil.str2longs(ids);
		articleService.batchDelCoreArticle(idList);
		this.corePlatformService.clearArticleCache();
		return new JsonResult().success();
	}

	@PostMapping(MODEL + "/excel/export.json")
	@Function("admin.article.export")
	@ResponseBody
	public JsonResult<String> export(HttpServletResponse response, ArticleQuery condtion) {
		/**
		 * 1)需要用你自己编写一个的excel模板
		 * 2)通常excel导出需要关联更多数据，因此articleService.queryByCondition方法经常不符合需求，需要重写一个为模板导出的查询
		 * 3)参考ConsoleDictController来实现模板导入导出
		 */
		String excelTemplate = "excelTemplates/admin/article/你的excel模板文件名字.xls";
		PageQuery<CmsArticle> page = condtion.getPageQuery();
		// 取出全部符合条件的
		page.setPageSize(Integer.MAX_VALUE);
		page.setPageNumber(1);
		page.setTotalRow(Integer.MAX_VALUE);
		// 本次导出需要的数据
		List<CmsArticle> list = articleService.queryByCondition(page).getList();
		try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(excelTemplate)) {
			if (is == null) {
				throw new PlatformException("模板资源不存在：" + excelTemplate);
			}
			FileItem item = fileService.createFileTemp("CoreArticle_" + DateUtil.now("yyyyMMddHHmmss") + ".xls");
			OutputStream os = item.openOutpuStream();
			Context context = new Context();
			context.putVar("list", list);
			JxlsHelper.getInstance().processTemplate(is, os, context);
			os.close();
			// 下载参考FileSystemContorller
			return JsonResult.success(item.getPath());
		} catch (IOException e) {
			throw new PlatformException(e.getMessage());
		}

	}

	@PostMapping(MODEL + "/excel/import.do")
	@Function("admin.article.import")
	@ResponseBody
	public JsonResult importExcel(@RequestParam("file") MultipartFile file) throws Exception {
		if (file.isEmpty()) {
			return JsonResult.fail();
		}
		InputStream ins = file.getInputStream();
		/* 解析模板并导入到数据库里,参考DictConsoleContorller，使用jxls reader读取excel数据 */
		ins.close();
		return JsonResult.success();
	}
	public JsonResult updateArticleTag(Long articleId, String ids) {
		List<Long> all = ConvertUtil.str2longs(ids);
		List<Long> addIds = new ArrayList<Long>();
		List<Long> delIds = new ArrayList<Long>();
		List<Long> dbs = articleTagService.getDictIdByArticleId(articleId);
		Iterator<Long> it = all.iterator();
		for(Long id:all) {
			if(!dbs.contains(id)) {
				addIds.add(id);
			}
		}

		for(Long id:dbs) {
			if(!all.contains(id)) {
				delIds.add(id);
			}
		}
		dictConsoleService.updateArticleDict(articleId, addIds, delIds);
		return JsonResult.success();
	}
}
